package com.avcompris.util;

import static com.avcompris.util.ExceptionUtils.nonNullArgument;
import static org.apache.commons.io.FileUtils.forceMkdir;
import static org.apache.commons.io.FileUtils.openOutputStream;
import static org.apache.commons.io.IOUtils.copy;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.avcompris.common.annotation.Nullable;

/**
 * Avantage Compris' utilities on I/O.
 * 
 * @author David Andriana Copyright Avantage Compris SARL 2008-2009 ©
 */
public abstract class AvcIOUtils extends AbstractUtils {

	/**
	 * copy the content of a resource to a destination file.
	 * 
	 * @param c the Java Class from which the resource has to be fetched
	 * @param resourcePath the path to the resource, relative to the Class'
	 *            ClassLoader
	 * @param destFile the destination file where to store the resource's
	 *            content
	 */
	public static void copyResource(
			final Class<?> c,
			final String resourcePath,
			final File destFile) throws IOException {

		nonNullArgument(destFile, "destFile");
		nonNullArgument(c, "class");
		nonNullArgument(resourcePath, "resourcePath");

		forceMkdir(destFile.getParentFile());

		final OutputStream os = openOutputStream(destFile);

		try {

			final InputStream is = c.getClassLoader().getResourceAsStream(
					resourcePath);

			if (is == null) {
				throw new FileNotFoundException("Cannot load resource: "
						+ resourcePath);
			}
			try {

				copy(is, os);

			} finally {
				is.close();
			}
		} finally {
			os.close();
		}
	}

	/**
	 * count the number of files within a directory, or return <tt>1</tt> if the
	 * given dir parameter is itself a plain file.
	 * 
	 * @param dir the directory to parse
	 * @return the number of files in the directory
	 */
	public static int countFiles(
			@Nullable final File dir) {

		if (dir == null || !dir.exists()) {
			return 0;
		} else if (!dir.isDirectory()) {
			return 1;
		}

		int count = 0;

		for (final File file : dir.listFiles()) {

			if (file.isDirectory()) {

				count += countFiles(file);

			} else {

				++count;
			}
		}

		return count;
	}
}
